#include "vsf.h"
#include "vsfjeg.h"

static vsf_err_t vsfjeg_udpate_frame(struct vsfjeg_t *jeg)
{
	uint32_t curtick = vsfhal_tickclk_get_ms();
	struct vsfui_fb_t *fb = &jeg->video.fb;
	vsf_err_t err;

#ifdef VSFJEG_CFG_DEBUG
	if (!jeg->video.start_tick)
	{
		jeg->video.start_tick = curtick;
		jeg->video.frame_cnt = 0;
	}
#endif

	vsfui_fb_unlock(fb);
	err = vsfui_fb_refresh(fb);
	vsfui_fb_lock(fb);
	if (err) return err;
	nes_setup_video(&jeg->nes.console, vsfui_fb_get_frame(&jeg->video.fb));

#ifdef VSFJEG_CFG_DEBUG
	jeg->video.frame_cnt++;
	if ((curtick - jeg->video.start_tick) >= 1000)
	{
		vsfdbg_printf("jeg: frame rate %d" VSFCFG_DEBUG_LINEEND,
				jeg->video.frame_cnt);
		jeg->video.start_tick = 0;
	}
#endif
	return VSFERR_NONE;
}

extern vsf_err_t vsfjeg_decoder_init(struct vsfjeg_decoder_t *decoder,
		struct vsfav_stream_t *stream);
void vsfjeg_init(struct vsfjeg_t *jeg)
{
	struct vsfui_fb_t *fb = &jeg->video.fb;

	jeg->started = false;
	jeg->video.updating = false;
	fb->screen.width = 256;
	fb->screen.height = 240;
	fb->screen.pixel_bitsize = 8;
	fb->screen.copy = false;
	fb->screen.refresh_interval = -1;
	jeg->video.buflist[0] = jeg->video.buffer[0];
	jeg->video.buflist[1] = jeg->video.buffer[1];
	vsfui_fb_init(&jeg->video.fb, jeg->video.buflist, dimof(jeg->video.buflist));

	vsfjeg_decoder_init(&jeg->video.decoder, &fb->av_stream);

	nes_init(&jeg->nes.console);
	if (nes_setup_rom(&jeg->nes.console, jeg->nes.rom.buffer, jeg->nes.rom.size))
		return;

	nes_setup_video(&jeg->nes.console, vsfui_fb_get_frame(&jeg->video.fb));

#ifdef VSFJEG_CFG_DEBUG
	jeg->video.start_tick = 0;
#endif
	jeg->started = true;
}

void vsfjeg_poll(struct vsfjeg_t *jeg)
{
	if (jeg->started)
	{
		if (!jeg->video.updating)
		{
			nes_set_controller(&jeg->nes.console, jeg->nes.controller[0],
				jeg->nes.controller[1]);
			nes_iterate_frame(&jeg->nes.console);
			if (nes_is_frame_ready(&jeg->nes.console))
				jeg->video.updating = true;
		}

		if (jeg->video.updating && !vsfjeg_udpate_frame(jeg))
			jeg->video.updating = false;
	}
}
